package com.tool.weixin;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;

import com.tool.weixin.cache.WeixinCacheManager;
import com.tool.weixin.message.BaseMessage;
import com.tool.weixin.message.aes.AesException;
import com.tool.weixin.message.aes.WXBizMsgCrypt;
import com.tool.weixin.message.type.EventType;
import com.tool.weixin.message.type.ReqType;
import com.tool.weixin.util.MessageUtil;
import com.tool.weixin.util.SignUtil;

public abstract class WeixinSupport {
	
	private static final Logger logger = org.slf4j.LoggerFactory.getLogger(WeixinSupport.class);
	
	protected static final String FROMUSERNAME = "FromUserName";
	protected static final String TOUSERNAME = "ToUserName";
	protected static final String EVENTKEY = "EventKey";
	protected static final String MSGTYPE = "MsgType";
	protected static final String EVENT = "Event";
	protected static final String MSGID = "MsgId";
	protected static final String CONTENT = "Content";
	
	public WeixinSupport() {
		init();
	}
    /**
     * 初始化方法
     */
	protected void init() {
		
	}
	
    /**
     * 处理微信服务器发来的请求
     * @author huff
     * @date 2016年5月23日
     * @param request
     * @return
     */
    protected String processRequest(HttpServletRequest request) {
    	String result = "";
    	WeixinCacheManager manager = WeixinCacheManager.getInstance();
    	String msgId = null;
    	try {
			Map<String, String> requestMap = MessageUtil.parseXml(request,WeixinConfig.getInstance().getAESKey());// xml请求解析
			logger.debug(requestMap.toString());
			msgId = requestMap.get(MSGID);
			if(manager.isExistMsgId(msgId)) {
				return "";
			} 
			String fromUserName = requestMap.get(FROMUSERNAME);
			String toUserName = requestMap.get(TOUSERNAME);
			String msgType = requestMap.get(MSGTYPE);
			
			BaseMessage msg = null;
			if(msgType.equals(ReqType.EVENT)) {//事件
				String eventType = requestMap.get(EVENT);
				if(eventType.equals(EventType.SUBSCRIBE)) {//订阅
					msg = handleSubscribe(requestMap);
					
				} else if(eventType.equals(EventType.CLICK)) {//单击事件
					msg = handleMenuClickEvent(requestMap);
					
				} else if(eventType.equals(EventType.VIEW)) {
					msg = handleMenuViewEvent(requestMap);
				}
				
				
			} else {
				if(msgType.equals(ReqType.TEXT)) { //文本消息
					msg = handleTextMsg(requestMap);
				}
			}
			
			if(msg != null) {
				msg.setToUserName(fromUserName);
				msg.setFromUserName(toUserName);
				msg.setCreateTime(new Date().getTime());
				msg.setFuncFlag(0);
				result = msg.toxml();
				if (StringUtils.isNotBlank(WeixinConfig.getInstance().getAESKey())) {
	                try {
	                    WXBizMsgCrypt pc = new WXBizMsgCrypt();
	                    result = pc.encryptMsg(result, request.getParameter("timestamp"), request.getParameter("nonce"));
	                    logger.debug("加密后密文:{}", result);
	                } catch (AesException e) {
	                	logger.error("加密异常", e);
	                }
	            }
			}
			
		} catch (Exception e) {
			logger.info("微信回复异常：",e);
			result = "";
		}
    	manager.removeMsgId(msgId);
		return result;
	}
    /**
     * 处理菜单view事件
     * @param requestMap
     * @return
     */
    protected BaseMessage handleMenuViewEvent(Map<String, String> requestMap) {
		return null;
	}

	/**
     * 处理菜单click事件
     * @author huff
     * @date 2016年5月23日
     * @param requestMap
     * @return
     */
    protected BaseMessage handleMenuClickEvent(Map<String, String> requestMap) {
		return null;
	}

	/**
     * 处理添加关注事件
     * @author huff
     * @date 2016年5月23日
     * @param requestMap
     * @return
     */
    protected BaseMessage handleSubscribe(Map<String, String> requestMap) {
		return null;
	}

	/**
	 * 处理文本消息，有需要是子类重写
	 * @author huff
	 * @date 2016年5月23日
	 * @param requestMap
	 * @return
	 */
    protected BaseMessage handleTextMsg(Map<String, String> requestMap) {
		return null;
	}

	/**
     * 验证请求
     * @author huff
     * @date 2016年5月23日
     * @param request
     * @return
     */
	protected boolean isLegal(HttpServletRequest request) {
		String signature = request.getParameter("signature");
        String timestamp = request.getParameter("timestamp");
        String nonce = request.getParameter("nonce");
        return SignUtil.checkSignature(WeixinConfig.getInstance().getToken(), signature, timestamp, nonce);
	}
	
	/**
	 * 绑定微信服务器
	 * @param request
	 * @param response
	 */
	protected void bind(HttpServletRequest request, HttpServletResponse response) {
		if (isLegal(request)) {
            //绑定微信服务器成功
        	PrintWriter out = null;;
			try {
				out = response.getWriter();
				out.print(request.getParameter("echostr"));
			} catch (IOException e) {
				e.printStackTrace();
			} finally{
				if(out != null) {
					out.close();
		            out = null;
				}
			}
        }
	}
	/**
	 * 微信消息交互处理
	 * @param request
	 * @param response
	 * @throws IOException
	 */
	protected void process(HttpServletRequest request, HttpServletResponse response) throws IOException {
		if (isLegal(request)) {
            String result = processRequest(request);
            //设置正确的 content-type 以防止中文乱码
            response.setContentType("text/xml;charset=UTF-8");
            PrintWriter writer = response.getWriter();
            writer.write(result);
            writer.close();
        }
	}
}
